package com.thon.service.system.impl;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.thon.dao.system.InterfacDao;
import com.thon.commons.utils.OrderedProperties;
import com.thon.entity.system.Interfac;
import com.thon.service.system.AuthService;

@Service(value = "authService")
@Transactional
public class AuthServiceImpl implements AuthService {

	private static final Log log = LogFactory.getLog(AuthServiceImpl.class);
	// 注意/r/n前不能有空格
	private static final String CRLF = "\r\n";	
	public static final String PREMISSION_STRING="perms[\"{0}\"]"; 
	public static final String REST_STRING="rest[\"{0}\"]"; 
	public static final String ROLES_STRING="roles[\"{0}\"]"; 
	@Autowired
	private InterfacDao InterfacDao;
	
	@Resource
	private ShiroFilterFactoryBean shiroFilterFactoryBean;

	@Override
	public String loadFilterChainDefinitions() {
		StringBuffer sb = new StringBuffer("");
		sb.append(getRestfulOperationAuthRule()).append(getFixedAuthRule());
		return sb.toString();
	}

	// 生成restful风格功能权限规则
	private String getRestfulOperationAuthRule(){
		List<Interfac> operations = InterfacDao.listInterfac();		
		StringBuffer sb = new StringBuffer("");
		if(operations!=null)
		for (Interfac op : operations) {			
			String url = op.getUrl();
			if(url!=null){
				if (!url.startsWith("/")) {
					url = "/" + url;
				}
				sb.append(url).append("=");
			
			Boolean flag=false;
			
			String authentication  = op.getAuthentication();
			if(authentication!=null)			
			{
				
				sb.append(authentication);
				sb.append(',');
			
			}
			
			String roles = op.getRole();
			if(roles!=null)
				sb.append(MessageFormat.format(ROLES_STRING,roles)); 
				
			String rest = op.getMethod();
			if(rest!=null)	
				sb.append(MessageFormat.format(REST_STRING,rest));  
			
			
			String permission = op.getPermission();
			if(permission!=null)
				sb.append(MessageFormat.format(PREMISSION_STRING,permission));  
			
				
				sb.append(CRLF);
			//sb.append(url).append("=").append("authc, rest[").append(url).append("]").append(CRLF);
			}
		}
		return sb.toString();

	    }

	/*
	 * //根据角色，得到动态权限规则 private String getDynaAuthRule() {
	 * 
	 * StringBuffer sb = new StringBuffer(""); Map<String, Set<String>> rules =
	 * newHashMap<String,Set<String>>();
	 * 
	 * List<Role> roles =
	 * dao.queryEntitys("from Role r left join fetch r.menus", newObject[]{});
	 * for(Role role: roles) { for(Iterator<Menu> menus
	 * =role.getMenus().iterator(); menus.hasNext();) { String url =
	 * menus.next().getUrl(); if(!url.startsWith("/")) { url = "/"+ url; }
	 * if(!rules.containsKey(url)) { rules.put(url, newHashSet<String>()); }
	 * rules.get(url).add((role.getRoleCode())); } }
	 * 
	 * for(Map.Entry<String, Set<String>> entry :rules.entrySet()) {
	 * sb.append(entry
	 * .getKey()).append(" = ").append("authc,roleOrFilter").append
	 * (entry.getValue()).append(CRLF); }
	 * 
	 * returnsb.toString(); }
	 */

	// 得到固定权限验证规则串
	private String getFixedAuthRule() {

		StringBuffer sb = new StringBuffer("");
		ClassPathResource cp = new ClassPathResource("auth.properties");
		Properties properties = new OrderedProperties();
		try {
			properties.load(cp.getInputStream());
		} catch (IOException e) {
			log.error("auth.properties error!", e);
			throw new RuntimeException("load auth.properties error!");
		}
		for (Iterator its = properties.keySet().iterator(); its.hasNext();) {
			
			String key = (String) its.next();
			if(!key.equals("<!--"))
			sb.append(key).append(" = ")
					.append(properties.getProperty(key).trim()).append(CRLF);

		}
		return sb.toString();

	}

	@Override
	// 此方法加同步锁
	public synchronized void reCreateFilterChains() {

		AbstractShiroFilter shiroFilter = null;
		try {
			shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject();
		} catch (Exception e) {
			         log.error("getShiroFilter from shiroFilterFactoryBean error!", e);
			throw new RuntimeException(
					"get ShiroFilter from shiroFilterFactoryBean error!");
		}

		PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver();
		DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver.getFilterChainManager();

		// 清空老的权限控制
		manager.getFilterChains().clear();

		shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();
		shiroFilterFactoryBean.setFilterChainDefinitions(loadFilterChainDefinitions());
		// 重新构建生成
		Map<String, String> chains = shiroFilterFactoryBean.getFilterChainDefinitionMap();
		for (Map.Entry<String, String> entry : chains.entrySet()) {
			String url = entry.getKey();
			String chainDefinition = entry.getValue().trim().replace(" ", "");
			manager.createChain(url, chainDefinition);
		}

	}

	@Override
	public String save(Interfac interfac) {
		
		 InterfacDao.save(interfac);
		 return "success";
	}

	@Override
	public void delete(Integer id) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void update(Interfac interfac) {
		// TODO Auto-generated method stub
		
	}

}